package com.yk.spark.controller.file;

import com.yk.spark.model.FileModel;
import com.yk.spark.model.cluster.ClusterModel;
import com.yk.spark.service.cluster.api.IClusterService;
import com.yk.spark.service.file.api.IFileService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.mapreduce.Cluster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Limit on 2017/8/23.
 */
@Controller
@RequestMapping("/file")
public class FileController {

    private final Log log= LogFactory.getLog(FileController.class);
    @Resource(name = "fileService")
    private IFileService fileService;
    @Resource(name = "clusterService")
    private IClusterService  clusterService;

    /**
     * 上传文件
     * @param file 客户端文件
     * @throws IOException 文件读写异常
     */
    @RequestMapping("uploadFile")
    @ResponseBody
    public void uploadFile(@RequestParam CommonsMultipartFile file,@RequestParam(name = "clusterId") String clusterId ,@RequestParam(name = "filePath") String filePath) throws IOException {

        // 判断是否有文件
        if (file != null && !file.isEmpty()) {

            ClusterModel model=this.clusterService.query(clusterId);

            String clusterPath="hdfs://"+model.getIp()+":"+model.getPort();

            // 获取文件的原始名称
            String fileName = file.getOriginalFilename();
            if (fileName.contains(" ")){
                fileName=fileName.replace(" ","-");
            }
            this.log.info(fileName+"\t准备上传");
            // 获取文件大小 单位：Byte->KB
            Long size = file.getSize()/1024;

            /* 执行文件上传与信息存储  */
            this.log.error(filePath);
            this.fileService.saveFile(new BufferedInputStream(file.getInputStream()), clusterPath+filePath, fileName,size);
        } else {
            this.log.info("空文件上传，上传结束");
        }
    }


    /**
     * 下载文件
     * @param fileId 文件唯一标识
     * @param response 客户端响应
     * @throws IOException 文件读写异常
     */
    @RequestMapping("downloadFile")
    @ResponseBody
    public void downloadFile(@RequestParam(name = "fileId") String fileId, HttpServletResponse response) throws IOException {
        FileModel model=this.fileService.getFileModel(fileId);
        this.log.info("下载文件："+model.getFileName());
        response.setHeader("content-type", "text/html;charset=UTF-8");
        response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(model.getFileName(),"utf-8"));
        this.fileService.downLoadFile(fileId, new BufferedOutputStream(response.getOutputStream()));
    }

    /**
     * 展示所有文件列表
     * @return  文件列表
     */
    @RequestMapping("listFile")
    @ResponseBody
    public Object listFile() {
        return this.fileService.getFileModel();
    }

    /**
     * 分页展示文件列表
     * @return  文件列表
     */
    @RequestMapping("listFilePage")
    @ResponseBody
    public Object listFilePage(
            @RequestParam(defaultValue = "1") int pageId
            , @RequestParam(defaultValue = "15") int limit) {
        Map<Object,Object> map= new HashMap<>();
        int start=(pageId-1)*limit;
        List<FileModel> fileModelList= this.fileService.getFileModel(start,limit);
        long totalPages=this.fileService.getFileModelTotal()/limit+1;
        map.put("result",fileModelList);
        map.put("total",totalPages);
        map.put("currentPage",pageId);
        return map;
    }


    /**
     * 删除文件
     * @param fileId 文件唯一标识
     * @return 操作状态
     */
    @RequestMapping("deleteFile")
    @ResponseBody
    public Object deleteFile(@RequestParam String fileId) {

        return this.fileService.deleteFile(fileId);
    }
}
